package zhoug.player.core;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.view.TextureView;
import android.view.ViewGroup;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;

/**
 * 播放器接口定义
 */
public interface ZPlayer {
    /**
     * 播放状态
     */
    @Documented
    @Retention(RetentionPolicy.SOURCE)
    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE})
    @IntDef({STATE_IDLE, STATE_START, STATE_PREPARED, STATE_PLAYING, STATE_PAUSE, STATE_ENDED})
    @interface State {
    }

    /**
     * 播放器处于初始状态,
     * 调用{@link #stopPlay()},{@link #release()}后的状态
     */
    int STATE_IDLE = 0;
    /**
     * 开始播放
     */
    int STATE_START = 1;
    /**
     * 资源准备好了
     */
    int STATE_PREPARED = 2;
    /**
     * 正在播放
     */
    int STATE_PLAYING = 3;
    /**
     * 暂停播放
     */
    int STATE_PAUSE = 4;

    /**
     * 播放完成了
     */
    int STATE_ENDED = 5;
    /**
     * 平铺模式：视频画面将会按照比例铺满屏幕，多余部分会被裁减掉，此模式下不会有黑边。
     */
    int RENDER_MODE_FULL_FILL_SCREEN = 0;
    /**
     * 自适应模式：视频画面将等比例缩放，会居中显示，此模式可能会有黑边
     */
    int RENDER_MODE_ADJUST_RESOLUTION = 1;
    /**
     * 高清
     */
    int QUALITY_HD = 1;
    /**
     * 标清
     */
    int QUALITY_SD = 0;

    /**
     * 设置上下文
     *
     * @param context 上下文
     */
    void setContext(@NonNull Context context);

    /**
     * 设置播放url
     *
     * @param url 播放url
     */
    void setPlayUrl(@Nullable String url);

    /**
     * 获取播放地址
     *
     * @return 播放url {@link #setPlayUrl(String)}设置的值
     */
    String getPlayUrl();

    /**
     * 设置显示页面
     *
     * @param textureView 预览界面
     */
    void setVideoTextureView(@Nullable TextureView textureView);

    /**
     * 设置PlayView容器
     *
     * @param viewGroup
     */
    void setPlayViewGroup(@Nullable ViewGroup viewGroup);

    /**
     * 设置播放渲染模式
     * 渲染模式有两种:
     * {@link #RENDER_MODE_FULL_FILL_SCREEN}平铺模式：视频画面将会按照比例铺满屏幕，多余部分会被裁减掉，此模式下不会有黑边。
     * {@link #RENDER_MODE_ADJUST_RESOLUTION}自适应模式：视频画面将等比例缩放，会居中显示，此模式可能会有黑边。
     *
     * @param renderMode {@link #RENDER_MODE_FULL_FILL_SCREEN,#RENDER_MODE_ADJUST_RESOLUTION}
     */
    void setRenderMode(int renderMode);

    /**
     * 设置播放渲染模式
     *
     * @return 渲染模式 {@link #RENDER_MODE_FULL_FILL_SCREEN,#RENDER_MODE_ADJUST_RESOLUTION}
     */
    int getRenderMode();

    /**
     * 设置静音
     *
     * @param mute true:静音,false:非静音
     */
    void setMute(boolean mute);

    /**
     * 是否是静音
     *
     * @return 是否是静音
     */
    boolean isMute();


    /**
     * 开始播放,每次都是重新加载资源播放,可以播放新的url
     */
    void startPlay();

    /**
     * 停止播放,会释放加载的媒体和资源
     */
    void stopPlay();

    /**
     * 如果正在播放则暂停播放,否则调用{@link #stopPlay()}停止播放
     */
    void pausePlay();

    /**
     * 如果暂停了或者资源已经准备好了则播放,否则{@link #startPlay()}重新开始播放
     */
    void resumePlay();


    /**
     * 释放资源,注意请把所有setXXX的数据设置为空
     */
    void release();

    /**
     * 是否正在播放
     *
     * @return 是否正在播放
     */
    boolean isPlaying();

    /**
     * 是否是停止 状态为{@link #STATE_IDLE,#STATE_ENDED}
     *
     * @return
     */
    boolean isStop();

    /**
     * 是否是暂停状态
     *
     * @return
     */
    boolean isPause();

    /**
     * 获取播放状态
     *
     * @return 播放状态 {@link State}
     */
    @State int getPlaySate();

    /**
     * 设置指定位置播放
     *
     * @param positionMs 毫秒
     */
    void seekTo(long positionMs);

    /**
     * 切换清晰度
     * {@link ZPlayer#QUALITY_SD,ZPlayer#QUALITY_HD}
     *
     * @param quality
     */
    void switchPlayQuality(int quality);

    /**
     * 切换为直播
     */
    void switchToLive();


    /**
     * 截屏,结果在{@link #setOnCapturePictureListener(OnCapturePictureListener)}中回掉
     *
     * @param path 截屏成功后保存的路径
     */
    void capturePicture(@NonNull String path);

    /**
     * 截屏
     *
     * @return 截屏的Bitmap
     */
    @Nullable
    Bitmap capturePicture();

    /**
     * 开始录制视频
     *
     * @param path 保存的视频地址,不一定使用
     */
    void startRecordVideo(String path);

    /**
     * 停止录制视频
     */
    void stopRecordVideo();

    /**
     * 设置对讲url
     *
     * @param talkUrl 对讲地址
     */
    void setTalkUrl(String talkUrl);

    /**
     * 开启对讲
     */
    void startVoiceTalk();

    /**
     * 停止对讲
     */
    void stopVoiceTalk();

    /**
     * 是否正在对讲
     *
     * @return 是否正在对讲
     */
    boolean isTalking();


    /**
     * 播放监听
     *
     * @param onPlayListener 播放监听器
     */
    void setOnPlayListener(@Nullable OnPlayListener onPlayListener);

    /**
     * 设置截屏回掉
     *
     * @param onCapturePictureListener 截屏结果回掉
     */
    void setOnCapturePictureListener(@Nullable OnCapturePictureListener onCapturePictureListener);

    /**
     * 设置视频录制回掉
     *
     * @param onVideoRecordListener 视频录制回掉
     */
    void setOnVideoRecordListener(@Nullable OnVideoRecordListener onVideoRecordListener);

    /**
     * 视频播放进度监听
     *
     * @param onPlayProgressListener 播放进度监听
     */
    void setOnPlayProgressListener(@Nullable OnPlayProgressListener onPlayProgressListener);

    /**
     * 设备能力集回掉
     *
     * @param onCameraAbilityCallback
     */
    void setOnCameraAbilityCallback(@Nullable OnCameraAbilityCallback onCameraAbilityCallback);

    /**
     * 摄像头设置回掉
     *
     * @param onCameraSettingCallback
     */
    void setOnCameraSettingCallback(@Nullable OnCameraSettingCallback onCameraSettingCallback);

    /**
     * 设置对讲监听
     *
     * @param onTalkListener 对讲监听
     */
    void setOnTalkListener(OnTalkListener onTalkListener);

    /**
     * 开启电子放大
     *
     * @param oRect
     * @param curRect
     */
    void openDigitalZoom(Rect oRect, Rect curRect);

    /**
     * 关闭电子放大
     */
    void closeDigitalZoom();

    /**
     * 自动获取设备能力集
     * @param autoGetAbility 默认false
     */
    void setAutoGetAbility(boolean autoGetAbility);

    /**
     * 自动获取设备设置
     * @param autoGetSettings 默认false
     */
    void setAutoGetSettings(boolean autoGetSettings);

    /**
     * 获取当前播放的时间
     * @return calenderTime 毫秒
     */
    long getCurrentTime();
}
